/**
 * CanvasManager Class
 * 
 * Manages the canvas context and provides rendering utilities.
 */
export class CanvasManager {
  private canvas: any; // Will be HTMLCanvasElement or node-canvas Canvas
  private context: any; // Will be CanvasRenderingContext2D
  private width: number;
  private height: number;

  /**
   * Creates an instance of CanvasManager.
   * @param width - Width of the canvas
   * @param height - Height of the canvas
   */
  constructor(width: number, height: number) {
    this.width = width;
    this.height = height;
    this.initializeCanvas();
  }

  /**
   * Initializes the canvas and context
   */
  private initializeCanvas(): void {
    console.log('Initializing canvas with dimensions:', this.width, 'x', this.height);
    try {
      // Try to use node-canvas if available (for Node.js environment)
      const { createCanvas } = require('canvas');
      this.canvas = createCanvas(this.width, this.height);
      this.context = this.canvas.getContext('2d');
      console.log('Node-canvas initialized successfully');
    } catch (e) {
      // Fallback for browser environment
      console.warn('Node-canvas not available, creating HTML canvas element');
      this.createBrowserCanvas();
    }
    
    this.setupContext();
    console.log('Canvas initialization completed');
  }

  /**
   * Creates an HTML canvas element for browser environments
   */
  private createBrowserCanvas(): void {
    console.log('Creating browser canvas element');
    if (typeof document !== 'undefined') {
      // Browser environment
      this.canvas = document.createElement('canvas');
      this.canvas.width = this.width;
      this.canvas.height = this.height;
      this.context = this.canvas.getContext('2d');
      console.log('Browser canvas created successfully');
    } else {
      // Non-browser environment without node-canvas
      console.error('No canvas implementation available');
      this.canvas = null;
      this.context = null;
    }
  }

  /**
   * Sets up the canvas context with default properties
   */
  private setupContext(): void {
    if (this.context) {
      this.context.imageSmoothingEnabled = true;
      this.context.textBaseline = 'top';
    }
  }

  /**
   * Gets the canvas element
   * @returns any - The canvas element
   */
  public getCanvas(): any {
    return this.canvas;
  }

  /**
   * Gets the canvas context
   * @returns any - The canvas context
   */
  public getContext(): any {
    return this.context;
  }

  /**
   * Clears the canvas
   */
  /**
   * Clears the canvas with transparent background
   */
  public clear(): void {
    console.log('Clearing canvas with transparent background');
    if (this.context) {
      // Clear with transparent background
      this.context.clearRect(0, 0, this.width, this.height);
      console.log('Canvas cleared');
    } else {
      console.warn('Canvas context is not available for clearing');
    }
  }

  /**
   * Resizes the canvas
   * @param width - New width
   * @param height - New height
   */
  public resize(width: number, height: number): void {
    console.log(`Resizing canvas from ${this.width}x${this.height} to ${width}x${height}`);
    this.width = width;
    this.height = height;
    
    if (this.canvas) {
      this.canvas.width = width;
      this.canvas.height = height;
      console.log('Canvas dimensions updated');
    } else {
      console.warn('Cannot resize: canvas element is not available');
    }
    
    this.setupContext();
    console.log('Canvas resized and context reconfigured');
  }

  /**
   * Gets the canvas width
   * @returns number - The canvas width
   */
  public getWidth(): number {
    return this.width;
  }

  /**
   * Gets the canvas height
   * @returns number - The canvas height
   */
  public getHeight(): number {
    return this.height;
  }

  /**
   * Converts the canvas to a data URL
   * @param type - Image format (default: 'image/png')
   * @param quality - Image quality for lossy formats (0-1)
   * @returns string - Data URL of the canvas
   */
  public toDataURL(type: string = 'image/png', quality?: number): string {
    console.log(`Converting canvas to data URL with type: ${type}`);
    if (this.canvas && typeof this.canvas.toDataURL === 'function') {
      const dataUrl = this.canvas.toDataURL(type, quality);
      console.log('Canvas converted to data URL successfully');
      return dataUrl;
    }
    
    console.warn('Canvas toDataURL function is not available');
    return ''; // Return empty string if not available
  }

  /**
   * Converts the canvas to a buffer (Node.js only)
   * @param type - Image format (default: 'image/png')
   * @param quality - Image quality for lossy formats (0-1)
   * @returns Buffer - Buffer of the canvas
   */
  public toBuffer(type: string = 'image/png', quality?: number): any {
    console.log('Converting canvas to buffer');
    if (this.canvas && typeof this.canvas.toBuffer === 'function') {
      const buffer = this.canvas.toBuffer(type, { quality });
      console.log(`Canvas converted to buffer with size: ${buffer.length} bytes`);
      return buffer;
    }
    
    console.warn('Canvas toBuffer function is not available');
    return null; // Return null if not available
  }
}